package cz.vse.javaee.album;

import javax.annotation.PostConstruct;
import javax.annotation.PreDestroy;
import javax.annotation.Resource;
import javax.ejb.EJBException;
import javax.ejb.LocalBean;
import javax.ejb.Stateless;
import javax.jms.*;
import javax.persistence.EntityManager;
import javax.persistence.PersistenceContext;
import javax.persistence.TypedQuery;
import java.util.Date;
import java.util.List;

/**
 * Tento bezstavový bean má na starosti export fotografií do JMS fronty. Při inicializaci vytvoření spojení
 * k JMS frontě, kterou drží otevřenou až do okamžiku jeho likvidace (metoda destroy).
 */
@Stateless
@LocalBean
public class Exporter {

    @PersistenceContext
    private EntityManager entityManager;
    @Resource(mappedName = "jms/exportQueueFactory")
    private ConnectionFactory connectionFactory;
    @Resource(mappedName = "jms/exportQueue")
    private Queue queue;

    private Connection connection;

    @PostConstruct
    private void init() {
        try {
            connection = connectionFactory.createConnection();
        } catch (JMSException e) {
            throw new EJBException(e);
        }
    }

    @PreDestroy
    private void destroy() {
        try {
            connection.close();
        } catch (JMSException e) {
            throw new EJBException();
        }
    }

    /**
     * Vybere fotografie v daným datumovým rozmezí a vyexportuje je do fronty.
     * @param from spodní limit výběru - včetně
     * @param to horní limit výběru - vyjma
     */
    public void exportPhotos(Date from, Date to) {
        try {
            TypedQuery<Photo> query = entityManager.createQuery(
                    "select p from Photo p where p.created >= :f and p.created < :t",
                    Photo.class);
            query.setParameter("f", from);
            query.setParameter("t", to);
            List<Photo> resultList = query.getResultList();

            Session queueSession = connection.createSession(true, Session.AUTO_ACKNOWLEDGE);
            MessageProducer producer = queueSession.createProducer(queue);

            for (Photo photo : resultList) {
                BytesMessage photoMessage = queueSession.createBytesMessage();
                photoMessage.writeBytes(photo.getImage());
                photoMessage.setStringProperty("name", photo.getName());
                photoMessage.setStringProperty("description", photo.getDescription());
                photoMessage.setStringProperty("albumName", photo.getAlbum().getName());
                photoMessage.setStringProperty("created", photo.getCreated().toString());
                photoMessage.setIntProperty("version", photo.getVersion());

                producer.send(photoMessage);
            }

        } catch (Exception e) {
            destroy();
            throw new EJBException(e);
        }
    }

}
